/**
 * Generate code from /gupbcloud-feign-api/gupbcloud-backend-{{projectName}}-api/src/main/java/{{packageName}}/framework/command/SSOResult.java.hbs
 */
package cn.ibizlab.core.authentication.domain;

import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.springframework.data.annotation.Transient;
import org.springframework.util.ObjectUtils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Getter
@Setter
@NoArgsConstructor
@Accessors(chain = true)
@JsonIgnoreProperties(value = "handler")
public class ExecutionResult<T> {

    private String code;
    private String message;
    private T data;

    @JsonIgnore
    @TableField(exist = false)
    @JSONField(serialize = false)
    @Transient
    private Map<String,Object> extensionParams=new HashMap<String,Object>();

    @JsonAnySetter
    @JSONField(name = "_any", unwrapped = true, serialize = false, deserialize = true)
    public void set(String field, Object value) {
        this.extensionParams.put(field,value);
    }

    private Map params;

    /**
     * 获取响应参数
     * @return
     */
    public Map getParams() {
        if(params == null){
            params = new HashMap();
            if(data != null && data instanceof Map)
                params = extractParam((Map<String, Object>) data);
            if(!ObjectUtils.isEmpty(extensionParams))
                params.putAll(extractParam(extensionParams));

            params.put("code",code);
            params.put("message",message);
        }
        return params;
    }

    /**
     * 递归解析参数，将树结构参数平铺展示
     * @param inParams
     * @return
     */
    private Map extractParam(Map<String,Object> inParams){
        Map params = new HashMap();
        if(ObjectUtils.isEmpty(inParams))
            return params;
        for(Map.Entry<String,Object> entry : inParams.entrySet()){
            Object value = entry.getValue();
            if(!ObjectUtils.isEmpty(value) && value instanceof List){
                for(Map param : (List<Map>)value){
                    params.putAll(extractParam(param));
                }
            }
            else if(!ObjectUtils.isEmpty(value) && value instanceof Map){
                params.putAll(extractParam((Map<String, Object>) value));
            }
            else{
                params.put(entry.getKey(),entry.getValue());
            }
        }
        return params;
    }

}